package com.example.maruko_course_backend.convertor;

import com.example.maruko_course_backend.dto.GrammarCategoryDto;
import com.example.maruko_course_backend.entity.Grammar;
import com.example.maruko_course_backend.vo.KnowledgeItemVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

import static com.example.maruko_course_backend.utils.DisplayStringUtil.addEnterCharForDisplay;
import static com.example.maruko_course_backend.utils.StringUtil.LINE_BREAK;

@Component
public class KnowledgeGrammarVoConvertor extends KnowledgeVoConvertor {
  
  @Autowired
  private GrammarHelper grammarHelper;
  
  public List<KnowledgeItemVo> createGrammarsVoByEntity(List<Grammar> grammars, List<String> displayedTop10Grammars) {
    if (CollectionUtils.isEmpty(grammars)) {
      return new ArrayList<>();
    }
    List<KnowledgeItemVo> grammarsVo = generateGrammarsVoByEntity(grammars);
    suppSeq(grammarsVo);
    return filterToDisplayItemVo(grammarsVo, displayedTop10Grammars);
  }
  
  private void suppSeq(List<KnowledgeItemVo> grammarsVo) {
    for (int i = 0; i < grammarsVo.size(); i++) {
      grammarsVo.get(i).setSeq(i);
    }
  }
  
  private List<KnowledgeItemVo> generateGrammarsVoByEntity(List<Grammar> grammars) {
    List<KnowledgeItemVo> grammarsVo = new ArrayList<>();
    for (GrammarCategoryDto grammarCategoryDto : grammarHelper.createGrammarCategoryDto(grammars)) {
      grammarsVo.addAll(getGrammarVoByDiffCategoryType(grammarCategoryDto));
    }
    return grammarsVo;
  }
  
  private List<KnowledgeItemVo> getGrammarVoByDiffCategoryType(GrammarCategoryDto grammarCategoryDto) {
    if (grammarHelper.isCombinedType(grammarCategoryDto.getCategory())) {
      return generateCombinedTypeGrammarsVo(grammarCategoryDto.getGrammars());
    }
    return generateSingleTypeGrammarsVo(grammarCategoryDto.getGrammars());
  }
  
  private List<KnowledgeItemVo> generateSingleTypeGrammarsVo(List<Grammar> singleTypeGrammars) {
    List<KnowledgeItemVo> grammarsVo = new ArrayList<>();
    for (Grammar singleTypeGrammar : singleTypeGrammars) {
      grammarsVo.add(createGrammarVoWithLineBreak(singleTypeGrammar.getContent()));
    }
    return grammarsVo;
  }
  
  private List<KnowledgeItemVo> generateCombinedTypeGrammarsVo(List<Grammar> grammars) {
    List<KnowledgeItemVo> grammarsVo = new ArrayList<>();
    for (List<Grammar> splitSameCategoryGrammar : grammarHelper.getSplitGrammars(grammars)) {
      grammarsVo.add(createGrammarVo(generateCombinedContent(splitSameCategoryGrammar)));
    }
    return grammarsVo;
  }
  
  private String generateCombinedContent(List<Grammar> grammars) {
    StringBuffer sb = new StringBuffer(grammars.get(0).getCategory()).append(LINE_BREAK);
    for (int i = 0; i < grammars.size(); i++) {
      sb.append(grammars.get(i).getContent());
      if (isNotLastElement(i, grammars.size())) {
        sb.append(LINE_BREAK);
      }
    }
    return sb.toString();
  }
  
  private boolean isNotLastElement(int i, int size) {
    return i != size - 1;
  }
  
  private KnowledgeItemVo createGrammarVoWithLineBreak(String content) {
    return KnowledgeItemVo.builder()
      .content(addEnterCharForDisplay(content))
      .build();
  }
  
  private KnowledgeItemVo createGrammarVo(String content) {
    return KnowledgeItemVo.builder()
      .content(content)
      .build();
  }
}
